/**
 * ！！！当前页面不应依赖项目中任何其他文件！！！
 * 除非确认该文件不会被其他文件依赖，否则不要在该文件中引入其他文件
 * ---------
 * 白名单
 * ./originalUtils.ts
 */
import { getCurrentRouteInfo } from "./originalUtils";
// 纯类型引入 无副作用
import type { RequestFailResult } from "@/api";

/** 项目命名空间 */
export const PROJECT_SPACE_NAME = "__PX_EVALUATE_MINI_APP__";

/** 开发环境刷新 */
export const DEV_RELOAD_CACHE_KEY = `${PROJECT_SPACE_NAME}-devReload`;

/**
 * 方法挂在点
 * --------
 * 用于挂载一些方法，比如获取token、退出登录、去登录页等
 * 本质避免循环引用
 */
const FUNC_MOUNT_TARGET = {
  /** 获取token */
  getToken: undefined as undefined | (() => string),
  /** 刷新Token */
  refreshToken: undefined as undefined | (() => Promise<void>),
  /** 退出登录 */
  logout: undefined as undefined | (() => void),
  /** 去登录页面 */
  goLoginPage: undefined as
    | undefined
    | ((params?: { from: string; type: "redirectTo" | "switchTab" }) => void),
};

/** 挂载获取用户token方法 */
export const mountGetTokenFunc = (
  fn: (typeof FUNC_MOUNT_TARGET)["getToken"],
) => {
  FUNC_MOUNT_TARGET.getToken = fn;
  console.log(`[mountGetTokenFunc] 挂载获取用户token方法`, FUNC_MOUNT_TARGET);
};

/** 挂载获取刷新Token方法 */
export const mountRefreshTokenFunc = (
  fn: (typeof FUNC_MOUNT_TARGET)["refreshToken"],
) => {
  FUNC_MOUNT_TARGET.refreshToken = fn;
  console.log(
    `[mountRefreshTokenFunc] 挂载获取刷新Token方法`,
    FUNC_MOUNT_TARGET,
  );
};

/** 处理业务错误结果 */
export interface DealBusinessErrorResult {
  /** 可以展示错误提示 */
  canShowErrorToast: boolean;
  /** 重新请求 */
  reload?: boolean;
  /** 新的错误 */
  newError: RequestFailResult;
}

/** 挂载退出登录方法 */
export const mountLogoutFunc = (fn: (typeof FUNC_MOUNT_TARGET)["logout"]) => {
  FUNC_MOUNT_TARGET.logout = fn;
  console.log(`[mountLogoutFunc] 挂载退出登录方法`, FUNC_MOUNT_TARGET);
};

/** 挂载去登录页方法 */
export const mountGoLoginPageFunc = (
  fn: (typeof FUNC_MOUNT_TARGET)["goLoginPage"],
) => {
  FUNC_MOUNT_TARGET.goLoginPage = fn;
  console.log(`[mountGoLoginPageFunc] 挂载去登录页方法`, FUNC_MOUNT_TARGET);
};

/** 请求配置 */
export const REQUEST_CONFIG = {
  /** 根地址 */
  basePath: import.meta.env.VITE_API_BASE_PATH,
  /** 超时时间 */
  timeout: 10000,
  /** 网关成功code列表 */
  gatewaySuccessCodeList: [200],
  /** 业务成功code列表 */
  businessSuccessCodeList: [200],
  /** 处理业务错误 */
  dealBusinessError: async (
    currentError: RequestFailResult,
  ): Promise<DealBusinessErrorResult> => {
    const { code, message, isBusinessError } = currentError;
    const res: DealBusinessErrorResult = {
      canShowErrorToast: true,
      newError: {
        code,
        message,
        isBusinessError,
      },
    };
    switch (code) {
      // token过期
      case 40002: {
        res.canShowErrorToast = false;
        try {
          await FUNC_MOUNT_TARGET.refreshToken?.();
          console.log(`[REQUEST_CONFIG] 刷新token成功`);
          res.reload = true;
        } catch (error) {
          console.log(`[REQUEST_CONFIG] 刷新token失败`, error);
          res.newError = error as RequestFailResult;
        }
        break;
      }
      // 未登录
      case 40005: {
        console.log(`[REQUEST_CONFIG] 未登录`, code, message);

        FUNC_MOUNT_TARGET.logout?.();

        // 判断当前页面如果不是登录页面，则跳转到登录页面
        // 判断逻辑根据项目自行判断
        const { path } = getCurrentRouteInfo();
        if (path !== "pages/login/index") {
          console.log(`[REQUEST_CONFIG] 当前页面不是登录页面，跳转到登录页面`);
          FUNC_MOUNT_TARGET.goLoginPage?.();
        } else {
          console.log(`[REQUEST_CONFIG] 当前页面是登录页面，不跳转`);
        }

        res.canShowErrorToast = false;
        break;
      }
      default: {
        console.log(`[REQUEST_CONFIG] 业务错误`, code, message);
      }
    }
    return res;
  },
  /** 获取请求头 */
  getHeader: () => {
    return {
      /** 客户端类型 */
      Terminal: import.meta.env.VITE_API_TERMINAL,
      Authorization: FUNC_MOUNT_TARGET.getToken?.() || "",
    };
  },
  /** 错误提示 */
  showToast: (message: string, show: boolean) => {
    show &&
      uni.showToast({
        title: message,
        icon: "none",
        duration: 2000,
      });
  },
};
